xen: Free initmem after boot. Mark lots of init functions as __init
authorKeir Fraser <keir@xensource.com>
Sat, 12 May 2007 09:28:53 +0000 (10:28 +0100)
committerKeir Fraser <keir@xensource.com>
Sat, 12 May 2007 09:28:53 +0000 (10:28 +0100)
that weren't before.
Signed-off-by: Keir Fraser <keir@xensource.com>
16 files changed:
xen/acm/acm_core.c
xen/arch/x86/domain_build.c
xen/arch/x86/extable.c
xen/arch/x86/mm.c
xen/arch/x86/setup.c
xen/arch/x86/x86_32/mm.c
xen/arch/x86/x86_64/mm.c
xen/common/gdbstub.c
xen/common/keyhandler.c
xen/common/page_alloc.c
xen/common/rcupdate.c
xen/common/trace.c
xen/drivers/char/console.c
xen/drivers/char/ns16550.c
xen/drivers/char/serial.c
xen/drivers/video/vga.c

index 2797604ee0c4e881a191b93e25c8b16bb9471b31..5cbff94bad8ce54fde3dde6778678f10733e0ccf 100644 (file)
@@ -269,7 +269,7 @@ acm_setup(char *policy_start,
 }
 
 
-int
+int __init
 acm_init(char *policy_start,
          unsigned long policy_len)
 {
index 4628160767895711a9de5832bbf5cfa56ca5dc90..3f491b5f7c90209e598523ba0a2ac4bfbb6fd5d7 100644 (file)
@@ -33,7 +33,9 @@
 extern unsigned long initial_images_nrpages(void);
 extern void discard_initial_images(void);
 
-static long dom0_nrpages, dom0_min_nrpages, dom0_max_nrpages = LONG_MAX;
+static long __initdata dom0_nrpages;
+static long __initdata dom0_min_nrpages;
+static long __initdata dom0_max_nrpages = LONG_MAX;
 
 /*
  * dom0_mem=[min:<min_amt>,][max:<max_amt>,][<amt>]
@@ -55,12 +57,12 @@ static long dom0_nrpages, dom0_min_nrpages, dom0_max_nrpages = LONG_MAX;
  *  If +ve: The specified amount is an absolute value.
  *  If -ve: The specified amount is subtracted from total available memory.
  */
-static long parse_amt(const char *s, const char **ps)
+static long __init parse_amt(const char *s, const char **ps)
 {
     long pages = parse_size_and_unit((*s == '-') ? s+1 : s, ps) >> PAGE_SHIFT;
     return (*s == '-') ? -pages : pages;
 }
-static void parse_dom0_mem(const char *s)
+static void __init parse_dom0_mem(const char *s)
 {
     do {
         if ( !strncmp(s, "min:", 4) )
@@ -103,7 +105,8 @@ string_param("dom0_ioports_disable", opt_dom0_ioports_disable);
 #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
 #define round_pgdown(_p)  ((_p)&PAGE_MASK)
 
-static struct page_info *alloc_chunk(struct domain *d, unsigned long max_pages)
+static struct page_info * __init alloc_chunk(
+    struct domain *d, unsigned long max_pages)
 {
     struct page_info *page;
     unsigned int order;
@@ -122,7 +125,7 @@ static struct page_info *alloc_chunk(struct domain *d, unsigned long max_pages)
     return page;
 }
 
-static unsigned long compute_dom0_nr_pages(void)
+static unsigned long __init compute_dom0_nr_pages(void)
 {
     unsigned long avail = avail_domheap_pages() + initial_images_nrpages();
 
@@ -151,7 +154,7 @@ static unsigned long compute_dom0_nr_pages(void)
     return dom0_nrpages;
 }
 
-static void process_dom0_ioports_disable(void)
+static void __init process_dom0_ioports_disable(void)
 {
     unsigned long io_from, io_to;
     char *t, *s = opt_dom0_ioports_disable;
@@ -189,10 +192,11 @@ static void process_dom0_ioports_disable(void)
     }
 }
 
-int construct_dom0(struct domain *d,
-                   unsigned long _image_start, unsigned long image_len, 
-                   unsigned long _initrd_start, unsigned long initrd_len,
-                   char *cmdline)
+int __init construct_dom0(
+    struct domain *d,
+    unsigned long _image_start, unsigned long image_len, 
+    unsigned long _initrd_start, unsigned long initrd_len,
+    char *cmdline)
 {
     int i, rc, compatible, compat32, order, machine;
     struct cpu_user_regs *regs;
index e8b620229e50b24ffe5a1242d681d63217e4d9a4..da822d34affa41403dc1173d5040bf5b2a335b93 100644 (file)
@@ -1,5 +1,6 @@
 
 #include <xen/config.h>
+#include <xen/init.h>
 #include <xen/perfc.h>
 #include <xen/spinlock.h>
 #include <asm/uaccess.h>
@@ -9,8 +10,8 @@ extern struct exception_table_entry __stop___ex_table[];
 extern struct exception_table_entry __start___pre_ex_table[];
 extern struct exception_table_entry __stop___pre_ex_table[];
 
-static void sort_exception_table(struct exception_table_entry *start,
-                                 struct exception_table_entry *end)
+static void __init sort_exception_table(struct exception_table_entry *start,
+                                        struct exception_table_entry *end)
 {
     struct exception_table_entry *p, *q, tmp;
 
@@ -28,7 +29,7 @@ static void sort_exception_table(struct exception_table_entry *start,
     }
 }
 
-void sort_exception_tables(void)
+void __init sort_exception_tables(void)
 {
     sort_exception_table(__start___ex_table, __stop___ex_table);
     sort_exception_table(__start___pre_ex_table, __stop___pre_ex_table);
index af9830571102766d2fb1fc67d8b5ff15ba4178d1..5e15ab13b0b3585013d89ea092fa29d2b1c6ba12 100644 (file)
@@ -184,7 +184,7 @@ void __init init_frametable(void)
     memset(frame_table, 0, nr_pages << PAGE_SHIFT);
 }
 
-void arch_init_memory(void)
+void __init arch_init_memory(void)
 {
     extern void subarch_init_memory(void);
 
index ea90e800e0661c5fdaac0f733064e66242efebde..09c81d98b9565ad42d41270c0b98dce5f2fe8aa1 100644 (file)
@@ -201,6 +201,14 @@ static void __init percpu_init_areas(void)
 #ifndef MEMORY_GUARD
     init_xenheap_pages(__pa(__per_cpu_start) + (first_unused << PERCPU_SHIFT),
                        __pa(__per_cpu_end));
+#endif
+    memguard_guard_range(&__per_cpu_start[first_unused << PERCPU_SHIFT],
+                         (NR_CPUS - first_unused) << PERCPU_SHIFT);
+#if defined(CONFIG_X86_64)
+    /* Also zap the mapping in the 1:1 area. */
+    memguard_guard_range(__va(__pa(__per_cpu_start)) +
+                         (first_unused << PERCPU_SHIFT),
+                         (NR_CPUS - first_unused) << PERCPU_SHIFT);
 #endif
 }
 
@@ -310,6 +318,24 @@ static void __init reserve_in_boot_e820(unsigned long s, unsigned long e)
     }
 }
 
+void init_done(void)
+{
+    extern char __init_begin[], __init_end[];
+
+    /* Free (or page-protect) the init areas. */
+#ifndef MEMORY_GUARD
+    init_xenheap_pages(__pa(__init_begin), __pa(__init_end));
+#endif
+    memguard_guard_range(__init_begin, __init_end - __init_begin);
+#if defined(CONFIG_X86_64)
+    /* Also zap the mapping in the 1:1 area. */
+    memguard_guard_range(__va(__pa(__init_begin)), __init_end - __init_begin);
+#endif
+    printk("Freed %ldkB init memory.\n", (long)(__init_end-__init_begin)>>10);
+
+    startup_cpu_idle_loop();
+}
+
 void __init __start_xen(multiboot_info_t *mbi)
 {
     char __cmdline[] = "", *cmdline = __cmdline;
@@ -895,7 +921,7 @@ void __init __start_xen(multiboot_info_t *mbi)
 
     domain_unpause_by_systemcontroller(dom0);
 
-    startup_cpu_idle_loop();
+    reset_stack_and_jump(init_done);
 }
 
 void arch_get_xen_caps(xen_capabilities_info_t *info)
index 802c0024804e3dbac83f79902361d7f32ec69631..29620a36ce2841b708bb452c5b3d1573de3b58ec 100644 (file)
@@ -159,7 +159,7 @@ void __init zap_low_mappings(l2_pgentry_t *base)
     flush_tlb_all_pge();
 }
 
-void subarch_init_memory(void)
+void __init subarch_init_memory(void)
 {
     unsigned long m2p_start_mfn;
     unsigned int i, j;
index 8328441cc0d08bbd59a3d82e60f53a2dd1501227..e5b6267f2c821b14c4e78b5f2454891e065bb6d3 100644 (file)
@@ -213,7 +213,7 @@ void __init zap_low_mappings(void)
     flush_tlb_all_pge();
 }
 
-void subarch_init_memory(void)
+void __init subarch_init_memory(void)
 {
     unsigned long i, v, m2p_start_mfn;
     l3_pgentry_t l3e;
index b9dfd08bbc611c05532544db33d7fa68654c0c63..51a2d6cb7defffca2e925fb41c1c8c3e5e6ff822 100644 (file)
@@ -584,7 +584,7 @@ __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
     return rc;
 }
 
-void
+void __init
 initialise_gdb(void)
 {
     gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
index 07658e0de000601f08c938adf686f79869d84e27..00f9afac0f2e8d2c98d4a1398a9c3a6020a9960a 100644 (file)
@@ -282,7 +282,7 @@ static void do_debug_key(unsigned char key, struct cpu_user_regs *regs)
                              bit. */
 }
 
-void initialize_keytable(void)
+void __init initialize_keytable(void)
 {
     open_softirq(KEYPRESS_SOFTIRQ, keypress_softirq);
 
index ea33153a7fcc56596d60aefe9f64334dedbebee0..47d31d344ba302e86d2610ba6d10759fb6d53e53 100644 (file)
@@ -50,7 +50,7 @@ string_param("badpage", opt_badpage);
  */
 static unsigned int  dma_bitsize = CONFIG_DMA_BITSIZE;
 static unsigned long max_dma_mfn = (1UL<<(CONFIG_DMA_BITSIZE-PAGE_SHIFT))-1;
-static void parse_dma_bits(char *s)
+static void __init parse_dma_bits(char *s)
 {
     unsigned int v = simple_strtol(s, NULL, 0);
     if ( v >= (BITS_PER_LONG + PAGE_SHIFT) )
@@ -74,7 +74,7 @@ custom_param("dma_bits", parse_dma_bits);
  * lowmem emergency pool.
  */
 static unsigned long dma_emergency_pool_pages;
-static void parse_dma_emergency_pool(char *s)
+static void __init parse_dma_emergency_pool(char *s)
 {
     unsigned long long bytes;
     bytes = parse_size_and_unit(s, NULL);
@@ -176,7 +176,7 @@ static void map_free(unsigned long first_page, unsigned long nr_pages)
 static unsigned long first_valid_mfn = ~0UL;
 
 /* Initialise allocator to handle up to @max_page pages. */
-paddr_t init_boot_allocator(paddr_t bitmap_start)
+paddr_t __init init_boot_allocator(paddr_t bitmap_start)
 {
     unsigned long bitmap_size;
 
@@ -197,7 +197,7 @@ paddr_t init_boot_allocator(paddr_t bitmap_start)
     return bitmap_start + bitmap_size;
 }
 
-void init_boot_pages(paddr_t ps, paddr_t pe)
+void __init init_boot_pages(paddr_t ps, paddr_t pe)
 {
     unsigned long bad_spfn, bad_epfn, i;
     const char *p;
@@ -243,7 +243,7 @@ void init_boot_pages(paddr_t ps, paddr_t pe)
     }
 }
 
-int reserve_boot_pages(unsigned long first_pfn, unsigned long nr_pfns)
+int __init reserve_boot_pages(unsigned long first_pfn, unsigned long nr_pfns)
 {
     unsigned long i;
 
@@ -258,7 +258,7 @@ int reserve_boot_pages(unsigned long first_pfn, unsigned long nr_pfns)
     return 1;
 }
 
-unsigned long alloc_boot_low_pages(
+unsigned long __init alloc_boot_low_pages(
     unsigned long nr_pfns, unsigned long pfn_align)
 {
     unsigned long pg, i;
@@ -281,7 +281,7 @@ unsigned long alloc_boot_low_pages(
     return 0;
 }
 
-unsigned long alloc_boot_pages(
+unsigned long __init alloc_boot_pages(
     unsigned long nr_pfns, unsigned long pfn_align)
 {
     unsigned long pg, i;
@@ -587,7 +587,7 @@ static unsigned long avail_heap_pages(
 
 #define avail_for_domheap(mfn) \
     (!allocated_in_map(mfn) && !is_xen_heap_frame(mfn_to_page(mfn)))
-void end_boot_allocator(void)
+void __init end_boot_allocator(void)
 {
     unsigned long i;
     int curr_free, next_free;
@@ -614,7 +614,7 @@ void end_boot_allocator(void)
  * convoluted than appears necessary because we do not want to continuously
  * hold the lock while scrubbing very large memory areas.
  */
-void scrub_heap_pages(void)
+void __init scrub_heap_pages(void)
 {
     void *p;
     unsigned long mfn;
index a67899a38e3652124d209c6f58407457b2556e79..676da1efe59a55e903bb451102de98aa9a483854 100644 (file)
@@ -341,7 +341,7 @@ void __devinit rcu_online_cpu(int cpu)
     rcu_init_percpu_data(cpu, &rcu_ctrlblk, rdp);
 }
 
-void rcu_init(void)
+void __init rcu_init(void)
 {
     rcu_online_cpu(smp_processor_id());
     open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
index 6fc4abe312550b38296a9507bb22796b912cf52c..5981f49bcd79fca553e4e272ab8262ae7912927f 100644 (file)
@@ -168,7 +168,7 @@ static int tb_set_size(int size)
  * trace buffers.  The trace buffers are then available for debugging use, via
  * the %TRACE_xD macros exported in <xen/trace.h>.
  */
-void init_trace_bufs(void)
+void __init init_trace_bufs(void)
 {
     if ( opt_tbuf_size == 0 )
     {
index d35a4c880926825648c91b0cedd4198b37e9ce86..33ad7aaaf1b711dfc3dc9ebab03f40ffe921832c 100644 (file)
@@ -121,7 +121,7 @@ static atomic_t print_everything = ATOMIC_INIT(0);
         return (lvlnum);                                \
     }
 
-static int __parse_loglvl(char *s, char **ps)
+static int __init __parse_loglvl(char *s, char **ps)
 {
     ___parse_loglvl(s, ps, "none",    0);
     ___parse_loglvl(s, ps, "error",   1);
@@ -132,7 +132,7 @@ static int __parse_loglvl(char *s, char **ps)
     return 2; /* sane fallback */
 }
 
-static void _parse_loglvl(char *s, int *lower, int *upper)
+static void __init _parse_loglvl(char *s, int *lower, int *upper)
 {
     *lower = *upper = __parse_loglvl(s, &s);
     if ( *s == '/' )
@@ -141,17 +141,17 @@ static void _parse_loglvl(char *s, int *lower, int *upper)
         *upper = *lower;
 }
 
-static void parse_loglvl(char *s)
+static void __init parse_loglvl(char *s)
 {
     _parse_loglvl(s, &xenlog_lower_thresh, &xenlog_upper_thresh);
 }
 
-static void parse_guest_loglvl(char *s)
+static void __init parse_guest_loglvl(char *s)
 {
     _parse_loglvl(s, &xenlog_guest_lower_thresh, &xenlog_guest_upper_thresh);
 }
 
-static char *loglvl_str(int lvl)
+static char * __init loglvl_str(int lvl)
 {
     switch ( lvl )
     {
@@ -504,7 +504,7 @@ void set_printk_prefix(const char *prefix)
     safe_strcpy(printk_prefix, prefix);
 }
 
-void init_console(void)
+void __init init_console(void)
 {
     char *p;
 
@@ -540,7 +540,7 @@ void init_console(void)
     }
 }
 
-void console_endboot(void)
+void __init console_endboot(void)
 {
     int i, j;
 
index ca491b35931a17498420b3970ea1f77badbca938..972eb6c05df29be63fa890d69a2452094eafce40 100644 (file)
@@ -170,7 +170,7 @@ static int ns16550_getc(struct serial_port *port, char *pc)
     return 1;
 }
 
-static void ns16550_init_preirq(struct serial_port *port)
+static void __init ns16550_init_preirq(struct serial_port *port)
 {
     struct ns16550 *uart = port->uart;
     unsigned char lcr;
@@ -214,7 +214,7 @@ static void ns16550_init_preirq(struct serial_port *port)
         port->tx_fifo_size = 16;
 }
 
-static void ns16550_init_postirq(struct serial_port *port)
+static void __init ns16550_init_postirq(struct serial_port *port)
 {
     struct ns16550 *uart = port->uart;
     int rc, bits;
@@ -250,7 +250,7 @@ static void ns16550_init_postirq(struct serial_port *port)
 }
 
 #ifdef CONFIG_X86
-static void ns16550_endboot(struct serial_port *port)
+static void __init ns16550_endboot(struct serial_port *port)
 {
     struct ns16550 *uart = port->uart;
     if ( ioports_deny_access(dom0, uart->io_base, uart->io_base + 7) != 0 )
@@ -276,7 +276,7 @@ static struct uart_driver ns16550_driver = {
     .irq          = ns16550_irq
 };
 
-static int parse_parity_char(int c)
+static int __init parse_parity_char(int c)
 {
     switch ( c )
     {
@@ -300,7 +300,8 @@ static int parse_parity_char(int c)
         return;                              \
     } while ( 0 )
 
-static void ns16550_parse_port_config(struct ns16550 *uart, const char *conf)
+static void __init ns16550_parse_port_config(
+    struct ns16550 *uart, const char *conf)
 {
     int baud;
 
@@ -360,7 +361,7 @@ static void ns16550_parse_port_config(struct ns16550 *uart, const char *conf)
     serial_register_uart(uart - ns16550_com, &ns16550_driver, uart);
 }
 
-void ns16550_init(int index, struct ns16550_defaults *defaults)
+void __init ns16550_init(int index, struct ns16550_defaults *defaults)
 {
     struct ns16550 *uart = &ns16550_com[index];
 
index cd909a6cef3012d60ce0aa40bf1a9eb106a2da07..8ec6ca6bd23a1d53726e66375acb88f78af109a8 100644 (file)
@@ -348,7 +348,7 @@ int serial_tx_space(int handle)
     return SERIAL_TXBUFSZ - (port->txbufp - port->txbufc);
 }
 
-void serial_init_preirq(void)
+void __init serial_init_preirq(void)
 {
     int i;
     for ( i = 0; i < ARRAY_SIZE(com); i++ )
@@ -356,7 +356,7 @@ void serial_init_preirq(void)
             com[i].driver->init_preirq(&com[i]);
 }
 
-void serial_init_postirq(void)
+void __init serial_init_postirq(void)
 {
     int i;
     for ( i = 0; i < ARRAY_SIZE(com); i++ )
@@ -364,7 +364,7 @@ void serial_init_postirq(void)
             com[i].driver->init_postirq(&com[i]);
 }
 
-void serial_endboot(void)
+void __init serial_endboot(void)
 {
     int i;
     for ( i = 0; i < ARRAY_SIZE(com); i++ )
index 303210e4666d06170712a18e9fe8a127650599e5..4facc145d04a80019ade66d96dcea657415e2906 100644 (file)
@@ -299,7 +299,7 @@ static inline void vga_wattr(void __iomem *regbase, uint8_t reg, uint8_t val)
     vga_w(regbase, VGA_ATT_W, val);
 }
 
-static int detect_video(void *video_base)
+static int __init detect_video(void *video_base)
 {
     volatile u16 *p = (volatile u16 *)video_base;
     u16 saved1 = p[0], saved2 = p[1];
@@ -322,7 +322,7 @@ static int detect_video(void *video_base)
 }
 
 /* This is actually code from vgaHWRestore in an old version of XFree86 :-) */
-static void *setup_vga(void)
+static void * __init setup_vga(void)
 {
     /* The following VGA state was saved from a chip in text mode 3. */
     static unsigned char regs[] = {
@@ -382,7 +382,7 @@ static void *setup_vga(void)
     return NULL;
 }
 
-static int vga_set_scanlines(unsigned scanlines)
+static int __init vga_set_scanlines(unsigned scanlines)
 {
     unsigned vtot, ovr, vss, vbs;
     uint8_t vse, vbe, misc = 0;
@@ -459,7 +459,7 @@ static int vga_set_scanlines(unsigned scanlines)
 static unsigned font_slot = 0;
 integer_param("fontslot", font_slot);
 
-static int vga_load_font(const struct font_desc *font, unsigned rows)
+static int __init vga_load_font(const struct font_desc *font, unsigned rows)
 {
     unsigned fontheight = font ? font->height : 16;
     uint8_t fsr = vga_rcrt(vgabase, VGA_CRTC_MAX_SCAN); /* Font size register */
@@ -573,7 +573,7 @@ string_param("vga", opt_vga);
 #define ATTRIBUTE   7
 #define VIDEO_SIZE  (COLUMNS * LINES * 2)
 
-void vga_init(void)
+void __init vga_init(void)
 {
     char *p;
 
@@ -624,7 +624,7 @@ void vga_init(void)
     vgacon_enabled = 1;
 }
 
-void vga_endboot(void)
+void __init vga_endboot(void)
 {
     if ( !vgacon_enabled )
         return;
@@ -670,7 +670,7 @@ void vga_putchar(int c)
     }
 }
 
-int fill_console_start_info(struct dom0_vga_console_info *ci)
+int __init fill_console_start_info(struct dom0_vga_console_info *ci)
 {
     memset(ci, 0, sizeof(*ci));